<?php
namespace DRY\Module;

/**
 * DonReY Framework 2012 :: Provides services for temporary storing of data, using various cache drivers
 * Caches are used to speed up scripts by storing data which would otherwise need to be assambled or read from a slower source.
 *
 * @author Wavetrex <wavetrex@gmail.com>
 * @link http://www.donrey.net/Documentation/Structure/Modules/cache.html
 * @license [GPL v3] http://www.gnu.org/licenses/gpl-3.0.html
 * @version 1.0.dev
 * @package DonReY
 * @subpackage Module.Cache
 */
class Cache extends base
{
	const
		Autoload_Directory = 'cache',
		Autoload_Prefix = 'DRY\Cache\Keystore',
		Autoload_Suffix = 'keystore'
		;

	/**
	 * Keys storage object. All storage objects must respond in the same way indifferent of the method they use to store data!
	 * @var \DRY\Cache\Keystore
	 */
	private $kStore;

	/**
	 * Module Constructor
	 * @param string $alias
	 * @param SimpleXMLElement $config
	 */
	public function __construct($alias, $config)
	{
		parent::__construct($alias, $config);

		// initialization of credentials handler/storage object
		$class_name=self::Autoload_Prefix.'_'.$this-> CFG-> storage['type'];
		$this-> kStore=new $class_name($this-> CFG-> storage, $this);

		if(isset($this-> CFG-> expire))
			$this-> kStore->_Set_Expire((int)$this-> CFG-> expire);
	}

	public function expire($limit = 0)
	{
		$this-> kStore->_Set_Expire($limit);
	}

	public function __set($key, $value)
	{
		$this-> kStore-> set($key, $value); // Todo: Expiry
	}

	public function __get($key)
	{
		return $this-> kStore-> get($key);
	}

	public function __unset($key) {
		$this-> kStore-> delete($key);
	}

	public function __isset($key) {
		return $this-> kStore-> check($key);
	}

	/**
	 * Check/Get/Set combo, which uses a callback to generate data if not found in cache, and cache that data
	 *
	 * @param string $key
	 * @param callable $callback
	 * @param array $param_arr Optional parameters for the callback
	 */
	public function test_Call($key, $callback, $param_arr = array())
	{
		// when data exists in cache, return it
		if($this-> kStore-> check($key)) {
			return $this-> kStore-> get($key);
		} else {
		// if not, use the callback
			$data = call_user_func_array($callback, $param_arr);
			$this-> kStore-> set($key, $data);
			return $data;
		}
	}

}

namespace DRY\Cache;

/**
 * Mandatory functions for Cache's Key-Storage system, used by the Cache module. Any type of data storage engine must implement these functions
 *
 * @author Wavetrex <wavetrex@gmail.com>
 * @link http://www.donrey.net/Documentation/Structure/Modules/cache.html
 * @license [GPL v3] http://www.gnu.org/licenses/gpl-3.0.html
 * @version 1.0.dev
 * @package DonReY
 * @subpackage Module.Cache
 */
interface Keystore
{
	public function set($key, $data);
	public function get($key);
	public function delete($key);
	public function check($key);
}
